
import bpy
import math

import Core.bl_渲染层 as 渲染层
from 节点.Core import bl_UI配色
import 全局控制.Node.节点和插座基类.bl_节点基类 as 基类
import 节点.Core.bl_Mesh as 网格操作


import 物体.物体管理.物体数据 as 物体数据

from 物体.物体管理 import engine_物体创建



from itertools import chain

import engine.initLIB.load_dll as engineLib
import ctypes









E_文件类型枚举 = [
	("pxy", "*.pxy", "", 0),
	("stl", "*.stl", "", 1),
	("obj", "*.obj", "", 2),
	("abc", "*.abc", "", 3),
	("bin", "*.RF_mesh_bin", "", 4),
]

def f_update_载入网格参数(self, context):
	data = (list(""), list(bpy.path.abspath(self.m_路径文本)), list(self.m_名称格式), list(self.m_文本类型), int(self.m_序列偏移), int(self.m_丢弃间隔))
	engineLib.flexCAPI.f_node_传入BL数据(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), ctypes.py_object(data));

def f_update_设置间隔(self, context):
	data = (list('间隔'), int(self.m_丢弃间隔))
	#print('间隔 = ', data)
	engineLib.flexCAPI.f_node_传入BL数据(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), ctypes.py_object(data));

def f_update更新后释放数据(self, context):
	engineLib.flexCAPI.f_set上层节点更新后释放数据(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), ctypes.c_bool(bool(self.m_是否更新后释放数据)));
	
class C_Node_载入网格(基类.C_Node_基类):
	bl_dname = 'bl_node_载入网格'
	bl_label = '载入网格'
	
	m_路径文本 = bpy.props.StringProperty(subtype='DIR_PATH', update=f_update_载入网格参数)
	m_名称格式 = bpy.props.StringProperty(update=f_update_载入网格参数)
	m_文本类型 = bpy.props.EnumProperty(items=E_文件类型枚举, name="类型", default="pxy", update=f_update_载入网格参数)
	m_序列偏移 = bpy.props.IntProperty(name="序列偏移", default=0, update=f_update_载入网格参数)
	m_丢弃间隔 = bpy.props.IntProperty(default=10, update=f_update_设置间隔)
	m_是否更新后释放数据 = bpy.props.BoolProperty(default=False, update=f_update更新后释放数据)

	
	
	def init(self, context):
		super(C_Node_载入网格, self).f_init(context)
		self.inputs.new('C_Socket_I32', name='编号')
		
		网格操作.f_创建网格插座(self, False)
		self.outputs.new('C_Socket_网格', name='网格')
		self.f_toCPP()
		
	def draw_buttons(self, context, layout):
		layout.prop(self, "m_路径文本")
		layout.prop(self, "m_名称格式", text='名称')
		layout.prop(self, "m_文本类型", text='后缀')
		layout.prop(self, "m_序列偏移", text='偏移')
		layout.prop(self, "m_丢弃间隔", text='丢弃')

	def draw_buttons_ext(self, context, layout):
		super(C_Node_载入网格, self).draw_buttons_ext(context, layout)
		layout.prop(self, 'm_是否更新后释放数据', icon='RESTRICT_RENDER_ON')
		
	def f_toCPP(self):
		engineLib.flexCAPI.f_创建Bl网格载入节点(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), self.f_getPyObject());
		f_update_载入网格参数(self, None)
		f_update_设置间隔(self, None)
		f_update更新后释放数据(self, None)
		self.use_custom_color = True
		self.color = bl_UI配色.g_内部节点颜色


class C_NODE_MENU_载入网格(bpy.types.Operator):
	bl_idname = 'node.global_node_load_mesh'
	bl_label = '载入网格'
	bl_options = {'REGISTER', 'UNDO'}
	def execute(operator, context):
		bpy.ops.node.add_node(type='C_Node_载入网格', use_transform=True)
		return {'FINISHED'}












def f_update_设置路径(self, context):
	data = (list('路径'), list(bpy.path.abspath(self.m_路径文本)))
	engineLib.flexCAPI.f_node_传入BL数据(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), ctypes.py_object(data));

def f_update_设置名称(self, context):
	data = (list('名称'), list(self.m_文件名称))
	engineLib.flexCAPI.f_node_传入BL数据(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), ctypes.py_object(data));

def f_update_设置后缀(self, context):
	data = (list('后缀'), list(self.m_文本后缀))
	engineLib.flexCAPI.f_node_传入BL数据(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), ctypes.py_object(data));

def f_update_设置偏移(self, context):
	data = (list('偏移'), int(self.m_序列偏移))
	engineLib.flexCAPI.f_node_传入BL数据(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), ctypes.py_object(data));



class C_Node_载入粒子(基类.C_Node_基类):
	bl_dname = 'bl_node_载入粒子'
	bl_label = '载入粒子'
	
	m_路径文本 = bpy.props.StringProperty(subtype='DIR_PATH', update=f_update_设置路径)
	m_文件名称 = bpy.props.StringProperty(update=f_update_设置名称)
	m_文本后缀 = bpy.props.EnumProperty(items=E_文件类型枚举, name="类型", default="pxy", update=f_update_设置后缀)
	m_序列偏移 = bpy.props.IntProperty(name="序列偏移", default=0, update=f_update_设置偏移)
	m_丢弃间隔 = bpy.props.IntProperty(default=10, update=f_update_设置间隔)
	m_是否更新后释放数据 = bpy.props.BoolProperty(default=False, update=f_update更新后释放数据)
	def init(self, context):
		super(C_Node_载入粒子, self).f_init(context)
		self.inputs.new('C_Socket_I32', name='编号')
		self.outputs.new('C_NodeSocket_粒子', name='粒子')
		self.f_toCPP()
		
	def draw_buttons(self, context, layout):
		layout.prop(self, "m_路径文本", text='路径')
		layout.prop(self, "m_名称格式", text='格式')
		layout.prop(self, "m_文本类型", text='后缀')
		layout.prop(self, "m_序列偏移", text='偏移')
		layout.prop(self, "m_丢弃间隔", text='丢弃')

	def draw_buttons_ext(self, context, layout):
		super(C_Node_载入粒子, self).draw_buttons_ext(context, layout)
		layout.prop(self, 'm_是否更新后释放数据', icon='RESTRICT_RENDER_ON')

	def f_toCPP(self):
		engineLib.flexCAPI.f_创建粒子载入节点(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), self.f_getPyObject());
		f_update_设置路径(self, None)
		f_update_设置名称(self, None)
		f_update_设置后缀(self, None)
		f_update_设置偏移(self, None)
		f_update_设置间隔(self, None)
		f_update更新后释放数据(self, None)
		self.use_custom_color = True
		self.color = bl_UI配色.g_内部节点颜色


class C_NODE_MENU_载入粒子(bpy.types.Operator):
	bl_idname = 'node.global_node_load_particle'
	bl_label = '载入粒子'
	bl_options = {'REGISTER', 'UNDO'}
	def execute(operator, context):
		bpy.ops.node.add_node(type='C_Node_载入粒子', use_transform=True)
		return {'FINISHED'}















E_网格类型文件枚举 = [
	("bobj", "bobj", "blender 流体网格", 0),
]

def f_update_路径(self, context):
	data= (list('path'), list(bpy.path.abspath(self.m_路径)))
	engineLib.flexCAPI.f_node_传入BL数据(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), ctypes.py_object(data));

def f_update_格式(self, context):
	data= (list('name'), list(self.m_格式))
	engineLib.flexCAPI.f_node_传入BL数据(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), ctypes.py_object(data));

def f_update_后缀(self, context):
	data= (list('type'), list(self.m_后缀))
	engineLib.flexCAPI.f_node_传入BL数据(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), ctypes.py_object(data));

def f_update_反向(self, context):
	data= (list('反向'), int(self.m_反向))
	engineLib.flexCAPI.f_node_传入BL数据(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), ctypes.py_object(data));

def f_update_预览(self, context):
	data= (list('预览'), int(self.m_预览))
	engineLib.flexCAPI.f_node_传入BL数据(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), ctypes.py_object(data));

class C_Node_保存网格(基类.C_Node_基类):
	bl_dname = 'bl_node_保存网格'
	bl_label = '保存网格'
	
	m_路径 = bpy.props.StringProperty(subtype='DIR_PATH', update=f_update_路径)
	m_格式 = bpy.props.StringProperty(update=f_update_格式)
	m_后缀 = bpy.props.EnumProperty(items=E_网格类型文件枚举, name="类型", default="bobj", update=f_update_后缀)
	m_反向 = bpy.props.BoolProperty(default=True, update=f_update_反向)
	m_预览 = bpy.props.BoolProperty(default=False, update=f_update_预览)
	def init(self, context):
		super(C_Node_保存网格, self).f_init(context)
		#f_创建网格插座(self, True)
		self.inputs.new('C_Socket_网格', name='网格')
		self.inputs.new('C_Socket_I32', name='编号')
		self.f_toCPP()
		
	def draw_buttons(self, context, layout):
		layout.prop(self, "m_路径")
		layout.prop(self, "m_后缀", text='后缀')
		if self.m_后缀 == 'bobj' :
			pass
		else:
			layout.prop(self, "m_格式", text='格式')

		row = layout.row()
		row.prop(self, "m_反向", text='反向')
		row.prop(self, "m_预览", text='预览')

	def f_toCPP(self):
		engineLib.flexCAPI.f_创建Bl网格保存节点(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), self.f_getPyObject());
		f_update_路径(self, None)
		f_update_格式(self, None)
		f_update_后缀(self, None)
		f_update_反向(self, None)
		f_update_预览(self, None)
		self.use_custom_color = True
		self.color = bl_UI配色.g_内部节点颜色
		
class C_NODE_MENU_保存网格(bpy.types.Operator):
	bl_idname = 'node.global_node_save_mesh'
	bl_label = '保存网格'
	bl_options = {'REGISTER', 'UNDO'}
	def execute(operator, context):
		bpy.ops.node.add_node(type='C_Node_保存网格', use_transform=True)
		return {'FINISHED'}























class C_Node_物体导入引擎(基类.C_Node_基类):
	bl_dname = 'bl_node_物体导入引擎'
	bl_label = '物体导入引擎'
	
	#m_路径文本 = bpy.props.StringProperty(subtype='DIR_PATH', update=f_update_载入网格参数)
	m_是否分割成三角形 = bpy.props.BoolProperty(default=True)
	#m_文本类型 = bpy.props.EnumProperty(items=E_文件类型枚举, name="类型", default="pyx", update=f_update_载入网格参数)
	def init(self, context):
		super(C_Node_物体导入引擎, self).f_init(context)
		#f_创建网格插座(self, True)
		self.inputs.new('C_Socket_物体集', name='物体集')
		self.outputs.new('C_Socket_I32', name='物体ID集')
		self.f_toCPP()
		
	def draw_buttons(self, context, layout):
		layout.prop(self, "m_是否分割成三角形")
	def f_toCPP(self):
		engineLib.flexCAPI.f_创建导入对象到引擎节点(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), self.f_getPyObject());
		#f_update_载入网格参数(self, None)
		
	def f_update(self):
		objs = self.inputs['物体集'].f_getData()
		data = []
		for obj in objs:
			顶点, 法线, UV, 索引 = 物体数据.f_get物体网格数据(obj, bpy.context, 导出三角面=self.m_是否分割成三角形)
			data.append([list(obj.type), obj.m_物体ID, 顶点, 法线, UV, 索引])
		engineLib.flexCAPI.f_node_传入BL数据(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), ctypes.py_object(data));
		#for obj, 物体ID in zip(objs, data):
		#	obj.m_物体ID = 物体ID
		物体ID集 = engineLib.flexCAPI.f_取VectorInt32插座节点数据(ctypes.c_wchar_p(self.id_data.name), 
																ctypes.c_wchar_p(self.name), 
																ctypes.c_wchar_p('物体ID集'), 
																ctypes.c_bool(True))
		for obj, ID in zip(objs, 物体ID集):
			obj.m_物体ID = ID

class C_NODE_MENU_物体导入引擎(bpy.types.Operator):
	bl_idname = 'node.global_node_objects_import_engine'
	bl_label = '物体导入引擎'
	bl_options = {'REGISTER', 'UNDO'}
	def execute(operator, context):
		bpy.ops.node.add_node(type='C_Node_物体导入引擎', use_transform=True)
		return {'FINISHED'}











'''class C_Node_灯光导入引擎(基类.C_Node_基类):
	bl_dname = 'bl_node_灯光导入引擎'
	bl_label = '灯光导入引擎'
	def init(self, context):
		super(C_Node_灯光导入引擎, self).f_init(context)
		self.inputs.new('C_Socket_集合', name='物体集')
		self.outputs.new('C_Socket_I32', name='编号')
		self.f_toCPP()
		
	def draw_buttons(self, context, layout):
		#layout.prop(self, "m_是否分割成三角形")
	def f_toCPP(self):
		#engineLib.flexCAPI.f_创建模型导入引擎节点(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name));
		pass
	def f_update(self):
		objs = self.inputs['物体集'].f_getData()
		
class C_NODE_MENU_灯光导入引擎(bpy.types.Operator):
	bl_idname = 'node.global_node_light_import_engine'
	bl_label = '灯光导入引擎'
	bl_options = {'REGISTER', 'UNDO'}
	def execute(operator, context):
		bpy.ops.node.add_node(type='C_Node_灯光导入引擎', use_transform=True)
		return {'FINISHED'}'''


import bpy_extras

class C_物体辅助(bpy_extras.object_utils.AddObjectHelper):
	@classmethod
	def poll(cls, context):
		print('bpy_extras.object_utils.AddObjectHelper')
		return True
	def view_align_update_callback(self, context):
		 print('view_align_update_callback --------- view_align_update_callback')




classes = (
	C_Node_载入网格,
	C_NODE_MENU_载入网格,

	C_Node_载入粒子,
	C_NODE_MENU_载入粒子,

	C_Node_保存网格,
	C_NODE_MENU_保存网格,


	C_Node_物体导入引擎,
	C_NODE_MENU_物体导入引擎,



	#C_物体辅助,

)


def register():
	for c in classes:
		bpy.utils.register_class(c)
		
	#bpy.utils.register_classes_factory(C_物体辅助)

def unregister():
	for c in classes:
		bpy.utils.unregister_class(c)




